package com.gzsxy.rabbitmq.producer.schedule;

import com.alibaba.fastjson.JSON;
import com.gzsxy.rabbitmq.producer.ConstantKey;
import com.gzsxy.rabbitmq.producer.config.redis.StringRedisTemplate;
import com.gzsxy.rabbitmq.producer.dto.DefalutBaseMessage;
import com.gzsxy.rabbitmq.producer.service.RabbitMQService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;

import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * @Description: 生产者失败消息重试
 * @Author: xiaolong
 * @date: 2023/2/15 16:57
 * @Version: 1.0
 */
@EnableScheduling
@Component
@ConditionalOnProperty(value = "rabbitmq.enable.type", havingValue = "reliable",matchIfMissing = false)
public class FailedMsgRetrySchedule {

    private final static Logger log = LoggerFactory.getLogger(FailedMsgRetrySchedule.class) ;

    private volatile boolean isRun = false;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RabbitMQService rabbitMQService;

    /**
     * 定时扫描生产者失败消息进行重试
     * @throws Exception
     *
     */
    @Scheduled(cron = "0 0/1 * * * ?")
    private void msgRetrySchedule() {
        if(!isRun){
            isRun = true ;
            try {
                failedMsgRetry();
            } catch (Exception e) {
                log.error("扫描生产者发送异常消息数据失败", e);
            }
            isRun = false ;
        }
    }


    /**
     * 失败消息重试
     */
    private void  failedMsgRetry(){
        //获取缓存中发送失败消息
        Map<String, Object> map = stringRedisTemplate.opsForHash().entries(ConstantKey.sendMsgStatus.FAIL.getValue());
        log.info("失败消息数据量=【{}】，json=【{}】",map.size(), JSON.toJSONString(map));
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            DefalutBaseMessage baseMessage = JSON.parseObject(JSON.toJSONString(value), DefalutBaseMessage.class);
            //重新发送rabbitmq
            rabbitMQService.sendMessageByExchange(baseMessage.getExchange(),baseMessage.getRoutingKey(),baseMessage.getMessage(), key);
        }
    }

}
